package com.example.utils;


import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.annotation.ExcelProperty;




import javax.servlet.http.HttpServletResponse;
import java.io.File;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.util.*;
import com.alibaba.excel.metadata.Sheet;

public class ExcelUtils {

    /**
     * 项目通用的Excel数据导出工具
     * @param name
     * @param objectMaps
     * @param stringStringMap
     * @return
     */
    public static String commonExcelMapList(String name, List<Map<String,Object>> objectMaps, Map<String, String> stringStringMap){
        String path=System.getProperty("user.dir");
        String excelName=String.valueOf(System.currentTimeMillis());
        String realPath=path+ File.separator+"excel"+File.separator+name+excelName+".xlsx";
        formartExcelMapListHead(realPath,objectMaps,stringStringMap);
        return realPath;
    }
    /**
     *动态头部
     * @param path  路径
     * @param objectMaps 数据集合
     * @param stringObjectMap  要做字段转换的Map
     */
    public static  void  formartExcelMapListHead(String path, List<Map<String, Object>> objectMaps, Map<String,String> stringObjectMap){
        if(objectMaps==null||objectMaps.size()==0){
            return;
        }
        List<List<String>> headList = new ArrayList<>();
        Map<String, Object> map=objectMaps.get(0);
        Set<String> strings=map.keySet();
        for (String key:strings){
            List<String> stringList=new ArrayList<>(1);
            String headName=null;
            if (stringObjectMap.containsKey(key)){
                headName=stringObjectMap.get(key);
            }else {
                headName=key;
            }
            stringList.add(headName);
            headList.add(stringList);
        }
        List<List<Object>> list = new ArrayList<>();
        for (int i = 0; i < objectMaps.size() ; i++) {
            List<Object> objects=new ArrayList<>(strings.size());
            Map<String, Object> objectMap1=objectMaps.get(i);
            for (String string: strings) {
                Object v=objectMap1.get(string);
                objects.add(v);
            }
            list.add(objects);
        }

    }

    public static void excelExportPath(String path,List<Map<String, Object>> objectMap){
        Map map=FormartExcelMapData(objectMap);
        List<List<String>> headList=(List<List<String>>) map.get("head");
        List<List<Object>> objects=(List<List<Object>>) map.get("list");

    }

    public static void excelEcportHttp(HttpServletResponse response,List<Map<String, Object>> objectList,String fileName) throws Exception{
        Map map=FormartExcelMapData(objectList);
        List<List<String>> headList=(List<List<String>>) map.get("head");
        List<List<Object>> objects=(List<List<Object>>) map.get("list");
        writeSimpleBySheet(response,headList,objects,null);

    }

    /**
     * 通用Map<String,Object>
     * @param objectMap
     */
    public static Map<String, Object> FormartExcelMapData(List<Map<String, Object>> objectMap){
        if(objectMap==null||objectMap.size()==0){
            return null;
        }
        Map<String, Object> map=objectMap.get(0);
        List<List<String>> headList = new ArrayList<List<String>>();
        Set<String> strings=map.keySet();
        for (String key:strings){
            List<String> stringList=new ArrayList<>(1);
            stringList.add(key);
            headList.add(stringList);
        }
        List<List<Object>> list = new ArrayList<>();
        for (int i = 0; i < objectMap.size() ; i++) {
            List<Object> objects=new ArrayList<>(strings.size());
            Map<String, Object> objectMap1=objectMap.get(i);
            for (String string: strings) {
                Object v=objectMap1.get(string);
                objects.add(v);
            }
            list.add(objects);
        }
        Map<String, Object> mapData=new HashMap<>();
        mapData.put("head",headList);
        mapData.put("list",list);
        return mapData;
    }


    /**
     * 通用bean
     * @param path
     * @param tList
     * @param <T>
     */
    public static <T> void formartExcelLiatBean(String path,List<T> tList){
        if(tList==null||tList.size()==0){
            return;
        }
        T t=tList.get(0);
        Class<T> cls=(Class<T>)t.getClass();
        Field[] fields=cls.getDeclaredFields();
        //添加头部集合
        List<List<String>> headList = new ArrayList<List<String>>();
        for (int i = 0; i < fields.length; i++) {
            Field field=fields[i];
            fields[i].setAccessible(true);
            String headName=null;
            if(field.isAnnotationPresent(ExcelProperty.class)){
                ExcelProperty excelProperty=field.getAnnotation(ExcelProperty.class);
                headName= excelProperty.value()[0];
            }else {
                headName=field.getName();
            }
            List<String> head=new ArrayList<>(1);
            head.add(headName);
            headList.add(head);
        }
        try {
            List<List<Object>> list = new ArrayList<>();
            for (int i = 0; i < tList.size(); i++) {
                List<Object> objects=new ArrayList<>(fields.length);
                T object=tList.get(i);
                for (int j = 0; j <fields.length ; j++) {
                    fields[j].setAccessible(true);
                    Object value=fields[j].get(object);
                    objects.add(value);
                }
                list.add(objects);
            }

        }catch (Exception e){
            e.printStackTrace();
        }
    }




    private static Sheet initSheet;

    static {
        initSheet = new Sheet(1, 0);
        initSheet.setSheetName("sheet");
        //设置自适应宽度
        initSheet.setAutoWidth(Boolean.TRUE);
    }



    public static void writeSimpleBySheet(HttpServletResponse response, List<List<String>> head, List<List<Object>> data,Sheet sheet) throws Exception{
        sheet = (sheet != null) ? sheet : initSheet;

//        if(head != null){
//            List<List<String>> list = new ArrayList<>();
//            head.forEach(h -> list.add(Collections.singletonList(h)));
//            sheet.setHead(list);
//        }
        sheet.setHead(head);

        OutputStream outputStream = null;
        ExcelWriter writer = null;
        try {
            outputStream=response.getOutputStream();
            writer = EasyExcelFactory.getWriter(outputStream);
            writer.write1(data,sheet);

        }finally {
            try {
                if(writer != null){
                    writer.finish();
                }

                if(outputStream != null){
                    outputStream.close();
                }

            } catch (IOException e) {

            }
        }
    }



}
